package netTools;

import java.net.InetAddress;
import java.util.Hashtable;
import java.util.Timer;
import java.util.Vector;

/**
 * A class which checks whatever an IP is allowed or not to communicate with server.
 * A "suspect" IP can be put in a warning list with a certain number of attempts: if an
 * IP is warned too many times it will be banned for a certain period.
 * 
 * @author pasquale
 *
 */
public class IPManager{
	private int N_TRIES_BEFORE_BAN;    
	private int BAN_TIME_MIN;
	private boolean mailSend;
	
	public IPManager(){
		mailSend = false;
		N_TRIES_BEFORE_BAN = 0;
		BAN_TIME_MIN = 0;
		warnedIPs = new Hashtable<InetAddress,Integer>();
		bannedIPs = new Vector<InetAddress>();
		timer = new Timer();
	}
	
	
	public IPManager(int nTries,int hBanTime, boolean mailSend){
		this();
		this.mailSend = mailSend;
		N_TRIES_BEFORE_BAN = nTries;
		BAN_TIME_MIN = hBanTime;
	}
	
	public boolean mailEnabled(){
		return mailSend;
	}
	
	/**
	 * 
	 * @param ipAddr
	 * @return true if the ip was banned due to too many tries
	 */
	public synchronized boolean addToWarned(InetAddress ipAddr){
		boolean banned = false;
		Integer warnLevel = warnedIPs.get(ipAddr);
		if(warnLevel == null)
			warnedIPs.put(ipAddr, 1);
		else if(warnLevel < N_TRIES_BEFORE_BAN ){
			warnLevel++;
			warnedIPs.put(ipAddr, warnLevel);
		}else{
			banned = true;
			warnedIPs.remove(ipAddr);
			bannedIPs.add(ipAddr);
			timer.schedule(new ReleaseBan(ipAddr,this), (60000*BAN_TIME_MIN) );
		}
		
		return banned;
	}
	
	public synchronized void addToBanned(InetAddress ipAddr){
		if(warnedIPs.get(ipAddr) != null)
			warnedIPs.remove(ipAddr);
		
		bannedIPs.add(ipAddr);
		if(BAN_TIME_MIN != 0)
			timer.schedule(new ReleaseBan(ipAddr,this), (72000*BAN_TIME_MIN) );
	}
	
	public synchronized boolean isBanned(InetAddress ipAddr){
		return bannedIPs.contains(ipAddr);
	}
	
	public synchronized void liftBan(InetAddress ipAddr){
		int index = bannedIPs.indexOf(ipAddr);
		if(index != -1)
			bannedIPs.removeElementAt(index);
	}
	
	public int getBanTime(){
		return BAN_TIME_MIN;
	}
	
	public int getNtriesBeforeBan(){
		return N_TRIES_BEFORE_BAN;
	}
	
	private Hashtable<InetAddress,Integer> warnedIPs;
	private Vector<InetAddress> bannedIPs;
	private Timer timer;
	
}
